package h5

import (
	"chess_platform/internal/alisdk"
	. "chess_platform/internal/common"
	"chess_platform/internal/login"
	"chess_platform/internal/token"
	"chess_platform/models/client"
	"chess_platform/models/h5"
	"chess_platform/modules"
	"fmt"
	"github.com/astaxie/beego/orm"
	"os"
	"time"
)

//[h5]用户
type UserController struct {
	GrantController
}

func (b *UserController) URLMapping() {
	b.Mapping("NewIdentity", b.NewIdentity)
	b.Mapping("AgentNum", b.AgentNum)
	b.Mapping("ChangeWeChat", b.ChangeWeChat)
	b.Mapping("SyncWeChat", b.SyncWeChat)
	b.Mapping("Card", b.Card)
	b.Mapping("BindGameId", b.BindGameId)
	b.Mapping("ChangePassword", b.ChangePassword)
	b.Mapping("BindNewPhone", b.BindNewPhone)
	b.Mapping("UnbindPhone", b.UnbindPhone)
	b.Mapping("GenAuthCode", b.GenAuthCode) //生成授权码
	b.Mapping("GetAuthCode", b.GetAuthCode) //获取授权码
	b.Mapping("Info", b.Info)
	b.Mapping("List", b.List)
	b.Mapping("UpdateAgentRemark", b.UpdateAgentRemark)
	b.Mapping("UpdatePlayerRemark", b.UpdatePlayerRemark)
	b.Mapping("ManualReview", b.ManualReview)
	b.Mapping("ListManualReview", b.ListManualReview)
	b.Mapping("StatManualReview", b.StatManualReview)
	b.Mapping("Logout", b.Logout)
	b.Mapping("ListNotice", b.ListNotice)
	b.Mapping("NoticeInfo", b.NoticeInfo)
	b.Mapping("NewFeedback", b.NewFeedback)
	b.Mapping("ListFeedbackRecord", b.ListFeedbackRecord)
	b.Mapping("ListHorse", b.ListHorse)
	b.Mapping("RefreshToken", b.RefreshToken)
	b.Mapping("FindPlayer", b.FindPlayer)
}

// @Title 新增实名认证
// @Description 新增实名认证
// @Param   identity  	     body    string  true      "身份证号码"
// @Param   real_name        body    string  true      "真实姓名"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /new-identity [post]
func (b *UserController) NewIdentity() {
	type Params struct {
		Identity string `json:"identity"`
		RealName string `json:"real_name"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Length(p.Identity, 18, "identity").Message("身份证号码长度为18位")
	b.Valid.Identity(p.Identity, "identity").Message("请收入正确的身份证,X为大写字母")
	b.Valid.MatchChinese(p.RealName, "real_name").Message("请输入中文")
	b.Valid.MinSize(p.RealName, 2, "real_name").Message("名字长度2-16")
	b.Valid.MaxSize(p.RealName, 16, "real_name").Message("名字长度2-16")
	if !b.VerifyParamsError() {
		return
	}

	data := map[string]interface{}{
		"identity":  p.Identity,
		"real_name": p.RealName,
	}
	//身份认证，纯粹做一下样子
	h5.UpdateUser(data, b.Uid)
	b.ResponseSuccess()

}

// @Title 获取一级代理的名额数
// @Description 获取一级代理的名额数
// @Success 0 {string} rest 为剩下名额
// @Success 1 {string} use  为已使用名额
// @Failure 399
// @router /agent-num [post]
func (b *UserController) AgentNum() {
	if !b.IsLevel1() {
		return
	}
	field := []string{"agent_num"}
	u, err := h5.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	if u == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrAuthCodeNotFound
		b.Response()
		return
	}
	count, err := h5.CountLevel2AgentNum(b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	data := map[string]interface{}{
		"rest": u.AgentNum,
		"use":  count,
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 更换微信
// @Description 更换微信
// @Param   code       body    string  true      "微信用户code"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /change-weChat [post]
func (b *UserController) ChangeWeChat() {
	field := []string{"login_type"}
	dbUser, err := h5.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if dbUser == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	if dbUser.LoginType != 2 {
		b.ResponseFail("手机登录才可以更换微信")
		return
	}

	type Params struct {
		Code string `json:"code" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	t, err := login.GetWeChatOpenIdAccessToken(p.Code)
	if err != nil {
		LogH5.Error(b.SystemError(err.Error()))
		return
	}
	if t.AccessToken == "" || t.OpenId == "" {
		LogH5.Error(b.SystemError(fmt.Sprintf("无效的open_id:%v\naccess_token:%v\n", t.OpenId, t.AccessToken)))
		return
	}

	//判断微信是否已经绑定了
	uu, err := h5.IsUserExistByOpenID(t.OpenId)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	//已经存在绑定了其它帐号，不能绑定此帐号
	if uu != nil { //already exist,can't bind
		b.Res.Code = ErrWeChatAlreadyBind
		b.Res.Msg = MsgErrWeChatAlreadyBind
		b.Response()
		return
	}

	weChat, err := login.GetWeChatUserInfo(t.AccessToken, t.OpenId)
	if err != nil {
		LogH5.Error(b.SystemError(err.Error()))
		return
	}
	if weChat == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}

	user := map[string]interface{}{
		"open_id":      weChat.OpenID,
		"nickname":     weChat.NickName,
		"sex":          weChat.Sex,
		"province":     weChat.Province,
		"city":         weChat.City,
		"head_img_url": weChat.HeadImgURL,
	}
	_, err = h5.UpdateUser(user, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 同步微信头像昵称
// @Description 同步微信头像昵称
// @Param   code       body    string  true      "微信用户code"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /sync-weChat [post]
func (b *UserController) SyncWeChat() {
	type Params struct {
		Code string `json:"code" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	t, err := login.GetWeChatOpenIdAccessToken(p.Code)
	if err != nil {
		LogH5.Error(b.SystemError(err.Error()))

		return
	}
	if t.AccessToken == "" || t.OpenId == "" {
		LogH5.Error(b.SystemError(fmt.Sprintf("无效的open_id:%v\naccess_token:%v\n", t.OpenId, t.AccessToken)))
		return
	}

	u, err := h5.IsUserExistByOpenID(t.OpenId)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	if u == nil { //doesn't exist
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrSyncWeChat
		b.Response()
		return
	}
	//用open_id去找出来的uid是否为b.Uid相等,不相等说明不是本帐号绑定的微信
	if u.Uid != b.Uid { //exist,but didn't match b.Uid
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrSyncWeChat
		b.Response()
		return
	}

	weChat, err := login.GetWeChatUserInfo(t.AccessToken, t.OpenId)
	if err != nil {
		LogH5.Error(b.SystemError(err.Error()))
		return
	}
	if weChat == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}

	user := map[string]interface{}{
		"open_id":      weChat.OpenID,
		"nickname":     weChat.NickName,
		"sex":          weChat.Sex,
		"province":     weChat.Province,
		"city":         weChat.City,
		"head_img_url": weChat.HeadImgURL,
	}
	_, err = h5.UpdateUser(user, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	b.ResponseSuccess()
}

// @Title 代理的名片(个人，店铺,下载APP的登录界面)(每次登录时才拉取,缓存在前端本地)
// @Description 代理的名片(个人，店铺)(每次登录时才拉取,缓存在前端本地)
// @Param   type  body    int  true      "2-代理名片,1-店铺名片,3-下载APP的登录界面"
// @Success 0 {string} QR-code图片文件路径
// @Failure 400
// @Failure 404
// @router /card [post]
func (b *UserController) Card() {
	type Params struct {
		Type int64 `json:"type" valid:"Range(1,3)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	typeName := ""
	if p.Type == 2 {
		typeName = "name"
		if !b.IsLevel1() {
			return
		}
		field := []string{"name_url", "head_img_url"}
		user, err := h5.SpecifyUserInfoById(b.Uid, field)
		if err != nil {
			LogH5.Error(b.DatabaseError(err.Error()))
			return
		}
		ossPath := ""
		if user != nil && user.NameUrl != "" {
			ossPath = user.NameUrl
		} else {
			ossPath, err = h5.MakeNameQRCode2(b.Uid, user.HeadImgUrl)
			if err != nil {
				LogH5.Error(b.DatabaseError(err.Error()))
				return
			}
		}
		b.Res.Data = alisdk.GetOssPathUrl(OssDomain) + "/" + ossPath
		b.ResponseSuccess()
	} else if p.Type == 1 {
		typeName = "shop"
		field := []string{"shop_url", "head_img_url"}
		user, err := h5.SpecifyUserInfoById(b.Uid, field)
		if err != nil {
			LogH5.Error(b.DatabaseError(err.Error()))
			return
		}
		ossPath := ""
		if user != nil && user.ShopUrl != "" {
			ossPath = user.ShopUrl
		} else {
			ossPath, err = h5.MakeShopQRCode2(b.Uid, user.HeadImgUrl)
			if err != nil {
				LogH5.Error(b.DatabaseError(err.Error()))
				return
			}
		}
		b.Res.Data = alisdk.GetOssPathUrl(OssDomain) + "/" + ossPath
		b.ResponseSuccess()
	} else {
		typeName = "login"
		field := []string{"login_url", "head_img_url"}
		user, err := h5.SpecifyUserInfoById(b.Uid, field)
		if err != nil {
			LogH5.Error(b.DatabaseError(err.Error()))
			return
		}
		ossPath := ""
		if user != nil && user.LoginUrl != "" {
			ossPath = user.LoginUrl
		} else {
			ossPath, err = h5.MakeLoginQRCode2(b.Uid, user.HeadImgUrl)
			if err != nil {
				LogH5.Error(b.DatabaseError(err.Error()))
				return
			}
		}
		b.Res.Data = map[string]interface{}{
			"login_url":   fmt.Sprintf("%v?agent_uid=%v", QRCode.LoginUrl, b.Uid),
			"qr_code_url": alisdk.GetOssPathUrl(OssDomain) + "/" + ossPath,
		}
		b.ResponseSuccess()
	}
	loginFile := fmt.Sprintf("login-%d.png", b.Uid)
	os.Remove(loginFile)
	shopFile := fmt.Sprintf("shop-%d.png", b.Uid)
	os.Remove(shopFile)
	qrFile := fmt.Sprintf("name-%v.png", b.Uid)
	os.Remove(qrFile)
	weChatFile := fmt.Sprintf("wechat-%v-%v.jpg", typeName, b.Uid)
	os.Remove(weChatFile)
	wordFile := fmt.Sprintf("word-%v-%v.jpg", typeName, b.Uid)
	os.Remove(wordFile)
	file := fmt.Sprintf("new-name-%v-%v.png", typeName, b.Uid)
	os.Remove(file)
}

// @Title 一级代理帮二级代理绑定二级代理的游戏id或绑定自己的id
// @Description 一级代理帮二级代理绑定二级代理的游戏id或绑定自己的id
// @Param   uid         body    string  true      "代理的用户id,绑定自己(代理)的时传0,一级代理帮名下的二级代理绑定传二级代理的uid"
// @Param   game_id     body    string  true      "代理的游戏id"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /bind-gameId [post]
func (b *UserController) BindGameId() {
	type Params struct {
		GameId int64 `json:"game_id" valid:"Required"`
		Uid    int64 `json:"uid"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	//查询此游戏用户id
	dbUser, err := client.QueryUserInfoById(p.GameId)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if dbUser.Uid == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "此游戏玩家ID不存在"
		b.Response()
		return
	}
	user := map[string]interface{}{
		"game_id": p.GameId,
	}
	var condition string
	if p.Uid == 0 { //绑定自己的游戏ID
		condition = fmt.Sprintf(" uid = %v ", b.Uid)
	} else {
		//只能更新自己名下的代理的game_id
		condition = fmt.Sprintf(" uid = %v AND pid = %v ", p.Uid, b.Uid)
	}
	_, err = h5.UpdateUserByCondition(user, condition)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	b.ResponseSuccess()
}

// @Title 修改密码
// @Description 修改密码
// @Param   old_password  body    string  true      "旧密码"
// @Param   new_password  body    string  true      "新密码"
// @Success 0 {string} 状态码
// @Failure 399
// @router /change-password [post]
func (b *UserController) ChangePassword() {
	type Params struct {
		OldPassword string `json:"old_password"`
		NewPassword string `json:"new_password"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.OldPassword, "old_password").Message("密码不能为空")
	b.Valid.MinSize(p.NewPassword, 6, "password").Message("密码长度为6-15个字符")
	b.Valid.MaxSize(p.NewPassword, 15, "password").Message("密码长度为6-15个字符")
	if !b.VerifyParamsError() {
		return
	}
	field := []string{"password"}
	u, err := h5.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	if u == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}

	if Md5sum(p.OldPassword) != u.Password {
		b.Res.Code = ErrUserPassword
		b.Res.Msg = MsgErrUserPassword
		b.Response()
		return
	}
	user := map[string]interface{}{
		"password": Md5sum(p.NewPassword),
	}

	_, err = h5.UpdateUser(user, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	b.ResponseSuccess()
}

// @Title 手机号绑定
// @Description 手机号绑定
// @Param   phone body    string  true      "手机号"
// @Param   captcha body    string  true      "验证码"
// @Success 0
// @Failure 400
// @Failure 404
// @router /bind-new-phone [post]
func (b *UserController) BindNewPhone() {
	type Params struct {
		Phone   string `json:"phone"`
		Captcha string `json:"captcha"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Phone, "phone").Message("手机号不能为空")
	b.Valid.Phone(p.Phone, "phone").Message("错误的手机号")
	b.Valid.Required(p.Captcha, "captcha").Message("验证码不能为空")
	b.Valid.Numeric(p.Captcha, "captcha").Message("验证码为6位数字")
	b.Valid.Length(p.Captcha, 6, "captcha").Message("验证码为6位数字")
	if !b.VerifyParamsError() {
		return
	}
	err, ok := alisdk.VerifySMSCaptcha(p.Phone, p.Captcha, KeyH5Phone, MemCache)
	if !ok {
		b.Res.Code = ErrCaptchaVerify
		b.Res.Msg = err.Error()
		b.Response()
		LogH5.Notice(err.Error())
		return
	}
	uid, err := h5.IsUserExistByPhone(p.Phone)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}

	if uid == b.Uid {
		b.ResponseSuccess("已经绑定,无需重复绑定")
		return
	}
	if uid != 0 {
		b.Res.Code = ErrUserAlreadyExist
		b.Res.Msg = MsgErrPhoneAlreadyExist
		b.Response()
		return
	}

	user := map[string]interface{}{
		"phone": p.Phone,
	}
	_, err = h5.UpdateUser(user, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	b.ResponseSuccess()
}

// @Title 解绑手机号
// @Description 解绑手机号
// @Param   phone     body    string  true      "旧手机号"
// @Param   captcha   body    string  true      "验证码"
// @Success 0 {string} 状态码
// @Failure 399
// @router /unbind-phone [post]
func (b *UserController) UnbindPhone() {
	type Params struct {
		Phone   string `json:"phone"`
		Captcha string `json:"captcha"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Phone(p.Phone, "phone").Message("请输入正确的原手机号")
	b.Valid.Required(p.Captcha, "captcha").Message("验证码不能为空")
	b.Valid.Numeric(p.Captcha, "captcha").Message("验证码为6位数字")
	b.Valid.Length(p.Captcha, 6, "captcha").Message("验证码为6位数字")
	if !b.VerifyParamsError() {
		return
	}

	err, ok := alisdk.VerifySMSCaptcha(p.Phone, p.Captcha, KeyH5Phone, MemCache)
	if !ok {
		b.Res.Code = ErrCaptchaVerify
		b.Res.Msg = err.Error()
		b.Response()
		return
	}

	uid, err := h5.IsUserExistByPhone(p.Phone)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	if uid != b.Uid {
		b.ResponseFail("请输入正确的手机号")
		return
	}

	//解绑手机号，所以把手机号置为空传过去就行了
	user := map[string]interface{}{
		"phone": "",
	}
	_, err = h5.UpdateUser(user, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	b.ResponseSuccess()

}

// @Title 生成授权码(每天一次)
// @Description 生成授权码(每天一次)
// @Success 0 {string} auth_code 授权码
// @Failure 399
// @router /gen-auth-code [post]
func (b *UserController) GenAuthCode() {
	if !b.IsLevel1() {
		return
	}
	//只有一级代理才能生成，并且每天只能生成一次
	ac, err := h5.AuthCodeInfoById(b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	//不用判断ac是否存在,因为如果ac不存在,ac.CreateTime为0,则isToday为false会进行下一步创建或更新授权码
	//授权码没有被使用且授权码生成的时间是今天
	if IsToday(ac.CreateTime) {
		b.Res.Code = ErrAuthCodeCantGenToday
		b.Res.Msg = MsgAuthCodeCantGenToday
		b.Response()
		return
	}

	//下面就是授权码被使用了，或授权码生成的时间不是今天
	//重新生成一个新的授权码
	newAuthCode, err := modules.GenOrUpdateAuthCode(b.Uid, Level2)
	if err != nil {
		LogH5.Error(b.SystemError(err.Error()))
		return
	}
	b.Res.Data = newAuthCode
	b.ResponseSuccess()
}

// @Title 获取授权码
// @Description 获取授权码,展示给代理自己看
// @Success 0 {string} auth_code 授权码
// @Failure 399
// @router /get-auth-code [post]
func (b *UserController) GetAuthCode() {
	ac, err := h5.AuthCodeInfoById(b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	authCode := ac.AuthCode
	//如果为空，说明初始化时没有正确生成授权码
	if ac.AuthCode == "" {
		newAuthCode, err := modules.GenOrUpdateAuthCode(b.Uid, Level2)
		if err != nil {
			LogH5.Error(b.SystemError(err.Error()))
			return
		}
		authCode = newAuthCode
	}

	b.Res.Data = authCode
	b.ResponseSuccess()
}

// @Title 获取自己用户信息
// @Description 获取自己用户信息
// @Success 0 {object} h5.User
// @router /info [post]
func (b *UserController) Info() {
	field := []string{"uid", "game_id", "nickname", "sex", "head_img_url", "phone", "level",
		"login_type", "identity", "real_name"}
	dbUser, err := h5.SpecifyUserInfoById(b.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if dbUser == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	dbUser.Phone = HidePhoneNumber(dbUser.Phone)
	b.Res.Data = map[string]interface{}{
		"uid":          dbUser.Uid,
		"game_id":      dbUser.GameId,
		"nickname":     dbUser.Nickname,
		"sex":          dbUser.Sex,
		"head_img_url": dbUser.HeadImgUrl,
		"phone":        dbUser.Phone,
		"level":        dbUser.Level,
		"login_type":   dbUser.LoginType,
		"identity":     dbUser.Identity,
		"real_name":    dbUser.RealName,
	}
	b.ResponseSuccess()
}

// @Title 获取二级代理列表(正式代理)
// @Description 获取二级代理列表(正式代理)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   name         body   string  false      "搜索用户名字"
// @Param   order        body   int     false      "0-升序,1-降序"
// @Param   type         body   int     false      "1-玩家数,2-代充,3-直充"
// @Success 0 {object} []h5.Level2Agent 二级列表
// @router /list [post]
func (b *UserController) List() {
	if !b.IsLevel1() {
		return
	}
	var p ListStatParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	//获取一级代理名下(正式代理)的二级代理列表
	users, count, err := h5.ListLevel2UserAndOrder(p, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}

	if len(users) == 0 { //没有更多的二级代理
		b.Res.Count = count
		b.Res.Code = ErrNoData
		b.Res.Msg = MsgErrNoData
		b.Response()
		return
	}

	b.Res.Data = users
	b.Res.Count = count
	b.ResponseSuccess()

}

// @Title 更新代理备注
// @Description 更新代理备注
// @Param   uid       body    int     true      "代理id"
// @Param   remark    body    string  true      "备注"
// @Success 0 {string} 状态码
// @Failure 399
// @router /update-agent-remark [post]
func (b *UserController) UpdateAgentRemark() {
	type Params struct {
		Uid    int64  `json:"uid"`
		Remark string `json:"remark"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.Uid, "uid").Message("代理id不能为空")
	b.Valid.MaxSize(p.Remark, 32, "remark").Message("最多能输入32个字符")
	if !b.VerifyParamsError() {
		return
	}
	u := map[string]interface{}{
		"remark": p.Remark,
	}
	_, err := h5.UpdateUser(u, p.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}

	b.ResponseSuccess()
}

// @Title 更新玩家备注
// @Description 更新玩家备注
// @Param   player_id        body    int     true      "玩家id"
// @Param   remark           body    string  true      "备注"
// @Success 0 {string} 状态码
// @Failure 399
// @router /update-player-remark [post]
func (b *UserController) UpdatePlayerRemark() {
	type Params struct {
		PlayerId int64  `json:"player_id"`
		Remark   string `json:"remark"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.PlayerId, "player_id").Message("玩家id不能为空")
	b.Valid.MaxSize(p.Remark, 32, "remark").Message("最多能输入32个字符")
	if !b.VerifyParamsError() {
		return
	}
	u := map[string]interface{}{
		"remark": p.Remark,
	}
	_, err := h5.UpdateOrInsertAgentPlayer(u, p.PlayerId, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 人工审核二级代理
// @Description 人工审核二级代理
// @Param   status         body   int     true       "4-通过，3-不通过"
// @Param   uid            body   int     true       "要审核的用户id"
// @Success 0 {string} 状态码
// @router /manual-review [post]
func (b *UserController) ManualReview() {
	if !b.IsLevel1() {
		return
	}
	type Params struct {
		Status int64
		Uid    int64
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Range(p.Status, 3, 4, "status").Message("输入不合法")
	b.Valid.Required(p.Uid, "uid").Message("用户id不能为空")
	if !b.VerifyParamsError() {
		return
	}
	//审核之前先判断下二级代理绑定了手机了没有
	field := []string{"status"}
	u, err := h5.SpecifyUserInfoById(p.Uid, field)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	if u.Status < BindPhoneSuccess {
		b.ResponseFail("代理还未绑定手机,请等待")
		return
	}

	o := orm.NewOrm()
	o.Using(DBChessCenter)
	o.Begin()
	defer o.Rollback()

	user := map[string]interface{}{
		"status": p.Status,
	}
	//更新被审核的代理状态
	_, err = h5.UpdateUser(user, p.Uid, o)
	if err != nil {
		o.Rollback()
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	//如果审核失败，就还原一个开通代理的名额
	if p.Status == VerifyNotPass {
		//更新自己的代理数加1
		_, err := h5.UpdateUserAgentNum(1, b.Uid, o)
		if err != nil {
			o.Rollback()
			LogH5.Error(b.DatabaseError(err.Error()))
			return
		}
	}
	o.Commit()
	b.ResponseSuccess()

}

// @Title 审核二级代理列表
// @Description 审核二级代理列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []h5.User
// @router /list-manual-review [post]
func (b *UserController) ListManualReview() {
	if !b.IsLevel1() {
		return
	}
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	users, err := h5.ListManualReviewUser(p, b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = users
	b.ResponseSuccess()
}

// @Title 统计未审核二级代理数
// @Description 统计未审核二级代理数
// @Success 0 {string} 未审核的数量
// @router /stat-manual-review [post]
func (b *UserController) StatManualReview() {
	if !b.IsLevel1() {
		return
	}
	count, err := h5.StatManualReviewUser(b.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 代理登出
// @Description 代理登出
// @Success 0 {string} 状态码
// @router /logout [post]
func (b *UserController) Logout() {
	key := fmt.Sprintf("%v%v", KeyH5TokenCache, b.Uid)
	err := RedisCache.Delete(key)
	if err != nil {
		LogH5.Error(b.SystemError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title H5公告列表(每次登录时拉取)
// @Description H5公告列表(每次登录时拉取)
// @Success 0 {object} []common.H5Notice 公告列表
// @router /list-notice [post]
func (b *UserController) ListNotice() {
	data, err := h5.ListNotice()
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title H5公告详情
// @Description H5公告详情
// @Param   id   body   int   true        "公告id"
// @Success 0 {object} []common.H5Notice 公告列表
// @router /notice-info [post]
func (b *UserController) NoticeInfo() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	data, err := h5.NoticeInfoById(p.Id)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))

		return
	}
	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 新建h5反馈
// @Description 新建h5反馈
// @Param   uid          body   int        false        "游戏玩家的id"
// @Param   game_name    body   string     false       "游戏名字"
// @Param   type         body   int        true        "标题"
// @Param   content      body   string     true        "内容"
// @Param   url          body   string     true        "多张图片的地址以"["url1","url2","url3"]"形式"
// @Success 0 {string}  状态码
// @router /new-feedback [post]
func (b *UserController) NewFeedback() {
	type Params struct {
		Uid      int64    `json:"uid"`
		GameName string   `json:"game_name"`
		Type     int64    `json:"type"`
		Content  string   `json:"content"`
		Url      []string `json:"url"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if len(p.Url) > 3 {
		b.ResponseFail("最多只能上传三张图片")
		return
	}

	b.Valid.Required(p.Type, "type").Message("请选择反馈类型")
	b.Valid.Required(p.Content, "content").Message("内容不能为空")
	if !b.ValidParams(&p) {
		return
	}
	data := map[string]interface{}{
		"uid":         b.Uid,
		"type":        p.Type,
		"content":     p.Content,
		"status":      0,
		"create_time": time.Now().Unix(),
	}
	o := NewDBOrm(DBChessCenter)
	o.Begin()
	defer o.Rollback()
	fid, err := h5.NewFeedback(data, o)
	if err != nil {
		o.Rollback()
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	dataUrl := map[string]interface{}{
		"fid": fid,
	}
	for _, v := range p.Url {
		dataUrl["url"] = v
		_, err := h5.NewFeedbackUrl(dataUrl, o)
		if err != nil {
			o.Rollback()
			LogH5.Error(b.DatabaseError(err.Error()))
			return
		}
	}
	o.Commit()
	b.ResponseSuccess()
}

// @Title h5用户反馈记录
// @Description h5用户反馈记录
// @Param   uid          body   int        false        "游戏玩家的id"
// @Param   page_size    body   int        true         "每页显示数量"
// @Param   page_index   body   int        true         "第几页"
// @Success 0 {string}  状态码
// @router /list-feedback-record [post]
func (b *UserController) ListFeedbackRecord() {
	type Params struct {
		Uid int64 `json:"uid"`
		ListParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	if p.Uid == 0 {
		data, count, err := h5.ListFeedbackRecord(p.ListParams, b.Uid)
		if err != nil {
			LogH5.Error(b.DatabaseError(err.Error()))
			return
		}
		b.Res.Count = count
		b.Res.Data = data
		b.ResponseSuccess()
	}

}

// @Title 跑马灯列表
// @Description 跑马灯列表
// @Success 0 {object} []common.Horse   跑马灯列表
// @router /list-horse  [post]
func (b *UserController) ListHorse() {
	//跑马灯类型,1-游戏客户端, 2-代理助手
	data, err := client.ListHorse(2)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = data
	b.ResponseSuccess()
}

// @Title 刷新token(定时刷新,每隔30分钟)
// @Description 刷新token(定时刷新,每隔30分钟)
// @Success 0 {string} 状态
// @router /refresh-token [post]
func (b *UserController) RefreshToken() {
	tokenStr := token.Create(b.Uid, 0, TokenH5, 1)
	key := fmt.Sprintf("%v%v", KeyH5TokenCache, b.Uid)
	RedisCache.Put(key, tokenStr, time.Duration(Secret.H5TokenCacheExpire)*time.Second)
	b.Res.Token = tokenStr
	b.ResponseSuccess()
}

// @Title 获取玩家信息
// @Description 获取玩家信息,代充前查找玩家id,以便确认
// @Param   uid  body    int     true      "玩家uid"
// @Success 0 {object} client.User
// @router /find-player [post]
func (b *UserController) FindPlayer() {
	type Params struct {
		Uid int64 `json:"uid"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Uid, "uid").Message("请输入正确的玩家ID")
	dbUser, err := client.QueryUserInfoById(p.Uid)
	if err != nil {
		LogH5.Error(b.DatabaseError(err.Error()))
		return
	}
	if dbUser.Uid == 0 {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrUserNotFound
		b.Response()
		return
	}
	data := map[string]interface{}{
		"uid":      dbUser.Uid,
		"nickname": dbUser.Nickname,
		"imageurl": dbUser.ImageUrl,
	}
	b.Res.Data = data
	b.ResponseSuccess()
}
